package cn.eclass.dao;

import cn.eclass.entity.Entity;
import cn.eclass.utils.Helper;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.apache.log4j.Logger;

public abstract class CommonDao {

    protected Connection conn;
    protected Logger logger = Helper.getLogger();
    private static final String POOLNAM = "eclass_localhost";

    public CommonDao(String className) {
    }

    public String ping() {
        return "OK";
    }

    Connection getLocalConnection() {
        Connection connection = null;
        String user = "root";
        String password = "freemysql";
        String url = "jdbc:mysql://localhost:3306/eclass?characterEncoding=utf8";
        String driver = "com.mysql.jdbc.Driver";
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user, password);
        } catch (SQLException ex) {
            logger.error(ex);
        } catch (ClassNotFoundException ex) {
            logger.error(ex);
        }
        return connection;

    }

    private Connection getConnection() throws NamingException {
        Connection connection = null;
        try {
            Context c = new InitialContext();
            DataSource ds = (DataSource) c.lookup("java:comp/env/local_eclass");
            connection = ds.getConnection();
        } catch (SQLException ex) {
            logger.error(ex);
        }
        return connection;
    }

    /**
     *
     * @param sql
     * @return ResultSet
     */
    protected List<? extends Entity> select(String sql) {

        List<Entity> beans = new ArrayList<Entity>();
        try {
            logger.info(sql);
            Connection connection = getLocalConnection();
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(sql);
            while (resultSet.next()) {
                beans.add(fillEntity(resultSet));
            }
            resultSet.close();
            statement.close();
            connection.close();
        } catch (Exception ex) {
            logger.error(ex);
        }
        return beans;
    }

    /**
     *parse ResultSet to HashMapList
     *
     * @param sql
     * @return
     */
    protected List<Map<String, String>> select2Map(String sql) {
        Connection connection = getLocalConnection();
        List result = new ArrayList();
        logger.info(sql);
        Statement statement;
        try {
            statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(sql);
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
            while (resultSet.next()) {
                Map resultEntry = new HashMap();
                for (int i = 1; i <= columnCount; i++) {
                    resultEntry.put(metaData.getColumnName(i), resultSet.getString(i));
                }
                result.add(resultEntry);
            }
        } catch (SQLException ex) {
            logger.error(ex);
        }

        return result;
    }

    protected int getItemCount(String sql) {
//		String sql = "select count(*) from schoolLink";
        int count = -1;
        logger.info(sql);
        Connection connection = getLocalConnection();
        Statement statement;
        try {
            statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(sql);
            while (resultSet.next()) {;
                count = resultSet.getInt(1);
            }
            resultSet.close();
            statement.close();
            connection.close();
        } catch (SQLException e) {
            logger.error(e);
        }
        return count;
    }

    protected int update(String sql) {
        int result = -1;// -1 is error, 0 is no rows effected;
        try {
            logger.info(sql);
            Connection connection = getLocalConnection();
            Statement statement = connection.createStatement();
            result = statement.executeUpdate(sql);
            statement.close();
            connection.close();
        } catch (Exception ex) {
            logger.error(ex);
        }
        return result;
    }

    protected int insert(String sql) {
        int key = -1;
        try {
            logger.info(sql);
            Connection connection = getLocalConnection();

            PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            statement.executeUpdate();
            ResultSet resultSet = statement.getGeneratedKeys();
            resultSet.next();
            key = resultSet.getInt(1);
            resultSet.close();
            statement.close();
            connection.close();
        } catch (Exception ex) {
            logger.error(ex);
        }
        return key;
    }

    protected int delete(String sql) {
        int result = -1;// -1 is error, 0 is no rows effected;
        try {
            logger.info(sql);
            Connection connection = getLocalConnection();
            Statement statement = connection.createStatement();
            result = statement.executeUpdate(sql);
            statement.close();
            connection.close();
        } catch (Exception ex) {
            logger.error(ex);
        }
        return result;
    }

    protected abstract Entity fillEntity(ResultSet resultSet);
}